﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Entity;

namespace Archie.Retail.Data.SqliteStorage
{
    public class SqliteDataManager : IDataManager
    {
        private readonly ArchieRetailContext _context;

        public SqliteDataManager()
        {
            _context = new ArchieRetailContext();
            _context.CheckTables();
        }

        
        public IEnumerable<Data.Door> GetDoors()
        {
//            return ((IObjectContextAdapter)_context)
//                                                  .ObjectContext
//                                                  .CreateObjectSet<Door>()
//                                                  .Include(d => d.DoorManufacturer)
//                                                  .Include(d => d.DoorSeries);
            return _context.Doors
                            .Include(d => d.DoorManufacturer)
                            .Include(d => d.DoorSeries)
                            .ToArray()
                            .Select(DataMapper.ToData);
        }

        public Data.Door GetDoor(Guid id)
        {
            return _context.Doors
                            .Include(d => d.DoorManufacturer)
                            .Include(d => d.DoorSeries)
                            .ToArray()
                            .Select(DataMapper.ToData)
                            .FirstOrDefault(d=>d.Id == id);
        }

        // вынести методы маппинга в класс, чтобы доставать связанные обекты из БД 
        // (контекста - аля произвДверей и СерииДверей. ТК мы уверены в том что их уже добавили в БД прежде)
        public void AddDoor(Data.Door door)
        {
            var sql = DataMapper.FromData(_context, door);
            sql.DoorManufacturer = _context.DoorManufacturers.Find(sql.DoorManufacturer.Id);
            sql.DoorSeries = _context.DoorSeries.Find(sql.DoorSeries.Id);
            
            _context.Doors.Add(sql);
            _context.SaveChanges();
        }

        public void UpdateDoor(Data.Door door)
        {
            var doorOrigin = _context.Doors.Find(door.Id);
            doorOrigin.Article = door.Article;

            if (doorOrigin.Image != door.Image)
            {
                doorOrigin.Image = door.Image;
            }
            if (doorOrigin.DoorManufacturer.Id != door.DoorManufacturerId)
            {
                doorOrigin.DoorManufacturer = _context.DoorManufacturers.Find(door.DoorManufacturerId);
            }
            if (doorOrigin.DoorSeries.Id != door.DoorSeriesId)
            {
                doorOrigin.DoorSeries = _context.DoorSeries.Find(door.DoorSeriesId);
            }
            
            doorOrigin.Article = door.Article;
            _context.SaveChanges();
        }

        public void DeleteDoor(Guid id)
        {
            _context.Doors.Remove(_context.Doors.Find(id));
            _context.SaveChanges();
        }

        
        public IEnumerable<Data.DoorManufacturer> GetDoorManufacturers()
        {
            return _context.DoorManufacturers.ToArray().Select(DataMapper.ToData);
        }

        public Data.DoorManufacturer GetDoorManufacturer(Guid id)
        {
            return DataMapper.ToData(_context.DoorManufacturers.Find(id));
        }

        public void AddDoorManufacturer(Data.DoorManufacturer doorManufacturer)
        {
            _context.DoorManufacturers.Add(DataMapper.FromData(doorManufacturer));
            _context.SaveChanges();
        }

        public void UpdateDoorManufacturer(Data.DoorManufacturer doorManufacturer)
        {
            var doorManufacturerOrigin = _context.DoorManufacturers.Find(doorManufacturer.Id);
            doorManufacturerOrigin.Name = doorManufacturer.Name;
            _context.SaveChanges();
        }

        public void DeleteDoorManufacturer(Guid id)
        {
            _context.DoorManufacturers.Remove(_context.DoorManufacturers.Find(id));
            _context.SaveChanges();
        }
        
        public IEnumerable<Data.DoorSeries> GetDoorSerieses()
        {
            return _context.DoorSeries.Select(ds=>DataMapper.ToData(ds));
        }

        public Data.DoorSeries GetDoorSeries(Guid id)
        {
            return DataMapper.ToData(_context.DoorSeries.Find(id));
        }

        public void AddDoorSeries(Data.DoorSeries doorSeries)
        {
            _context.DoorSeries.Add(DataMapper.FromData(doorSeries));
            _context.SaveChanges();
        }

        public void UpdateDoorSeries(Data.DoorSeries doorSeries)
        {
            var doorSeriesOrigin = _context.DoorSeries.Find(doorSeries.Id);
            doorSeriesOrigin.Name = doorSeries.Name;
            _context.SaveChanges();
        }

        public void DeleteDoorSeries(Guid id)
        {
            _context.DoorSeries.Remove(_context.DoorSeries.Find(id));
            _context.SaveChanges();
        }



        public IEnumerable<Data.HandleSeries> GetHandleSeries()
        {
            return _context.HandleSeries.Select(hs=>DataMapper.ToData(hs));
        }

        public Data.HandleSeries GetHandleSeries(Guid id)
        {
            return DataMapper.ToData(_context.HandleSeries.Find(id));
        }

        public void AddHandleSeries(Data.HandleSeries handleSeries)
        {
            _context.HandleSeries.Add(DataMapper.FromData(handleSeries));
            _context.SaveChanges();
        }

        public void UpdateHandleSeries(Data.HandleSeries handleSeries)
        {
            var handleSeriesOrigin = _context.HandleSeries.Find(handleSeries.Id);
            handleSeriesOrigin.Name = handleSeries.Name;
            _context.SaveChanges();
        }

        public void DeleteHandleSeries(Guid id)
        {
            _context.HandleSeries.Remove(_context.HandleSeries.Find(id));
            _context.SaveChanges();
        }

        
        
        public IEnumerable<Data.Handle> GetHandles()
        {
            return _context.Handles.Select(h=>DataMapper.ToData(h));            
        }
        
        public Data.Handle GetHandle(Guid id)
        {
            return DataMapper.ToData(_context.Handles.Find(id));
        }

        public void AddHandle(Data.Handle handle)
        {
            _context.Handles.Add(DataMapper.FromData(_context, handle));
            _context.SaveChanges();
        }

        public void DeleteHandle(Guid id)
        {
            _context.Handles.Remove(_context.Handles.Find(id));
            _context.SaveChanges();
        }

        public void UpdateHandle(Data.Handle handle)
        {
            var handleOrigin = _context.Handles.Find(handle.Id);
            handleOrigin.Article = handle.Article;

            if (handleOrigin.HandleSeries.Id != handle.HandleSeriesId)
            {
                handleOrigin.HandleSeries = _context.HandleSeries.Find(handle.HandleSeriesId);
            }

            _context.SaveChanges();
        }
    }
}